import 'dart:async';

import 'package:rxdart/rxdart.dart';

import '../../common/test_page.dart';
import '../utils.dart';

class DefaultIfEmptyTestPage extends TestPage {
  DefaultIfEmptyTestPage(super.title) {
    test('Rx.defaultIfEmpty.whenEmpty', () async {
      Stream<bool>.empty()
          .defaultIfEmpty(true)
          .listen(((bool result) {
        expect(result);
      }));
    });

    test('Rx.defaultIfEmpty.reusable', () async {
      final transformer = DefaultIfEmptyStreamTransformer<bool>(true);

      Stream<bool>.empty().transform(transformer).listen(((result) {
        expect(result);
      }));

      Stream<bool>.empty().transform(transformer).listen(((result) {
        expect(result);
      }));
    });

    test('Rx.defaultIfEmpty.whenNotEmpty', () async {
      Stream.fromIterable(const [false, false, false])
          .defaultIfEmpty(true)
          .listen(((result) {
        expect(result);
      }));
    });

    test('Rx.defaultIfEmpty.asBroadcastStream', () async {
      final stream = Stream.fromIterable(const <int>[])
          .defaultIfEmpty(-1)
          .asBroadcastStream();

      stream.listen(null);
      stream.listen(null);

      expect(stream.isBroadcast);
    });

    test('Rx.defaultIfEmpty.error.shouldThrow', () async {
      final streamWithError = Stream<int>.error(Exception()).defaultIfEmpty(-1);

      streamWithError.listen(null,
          onError: (Object e, StackTrace s) {
            expect(e);
          });
    });

    test('Rx.defaultIfEmpty.pause.resume', () async {
      late StreamSubscription<int> subscription;
      final stream = Stream.fromIterable(const <int>[]).defaultIfEmpty(1);

      subscription = stream.listen(((value) {
        expect(value);

        subscription.cancel();
      }));

      subscription.pause();
      subscription.resume();
    });
    test('Rx.defaultIfEmpty accidental broadcast', () async {
      final controller = StreamController<int>();

      final stream = controller.stream.defaultIfEmpty(1);

      stream.listen(null);
      expect(() => stream.listen(null));

      controller.add(1);
    });

    test('Rx.defaultIfEmpty.nullable', () {
      nullableTest<String?>(
            (s) => s.defaultIfEmpty(null),
      );
    });
  }

}